package com.helloandroid.tools

import com.helloandroid.AppUtil
import com.helloandroid.MyApplication
import com.helloandroid.ext.Json
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import java.io.BufferedReader
import java.io.DataOutputStream
import java.io.InputStreamReader
import java.lang.RuntimeException
import java.net.HttpURLConnection
import java.net.URL

object Http {
    const val BaseUrl = "https://service-1k4r2490-1301030645.gz.apigw.tencentcs.com/release/"
    const val HttpDebug = true

    const val NoNetwork = 1 // 无网络
    private const val ReqError = 2
    private const val ReadHttpResultError = 3

    fun noNetWorkError(): String {
        return Json {
            "err" to NoNetwork
            "msg" to "没有连接到网络"
        }.toString()
    }

    private fun responseError(responseCode: Int): String {
        return Json {
            "err" to ReqError
            "msg" to "请求失败,responseCode = $responseCode"
        }.toString()
    }

    private fun readHttpResultError(): String {
        return Json {
            "err" to ReadHttpResultError
            "msg" to "读取http返回错误"
        }.toString()
    }

     fun get(url: String, bRelative: Boolean = true): String {
        return try {
            AppUtil.reqSyncUser()
            tryGet(url, bRelative)
        } catch (e: Exception) {
            Json {
                "err" to 1000
                "msg" to "客户端tryGet错误"
            }.toString()
        }
    }

//    private fun okHttpGet(url: String): String? {
//        val client = OkHttpClient()
//        val request: Request = Request.Builder()
//                .url(url)
//                .build()
//        client.newCall(request).execute().use { response -> return response.body?.string() }
//    }

      fun tryGet(urlStr: String, bRelative: Boolean = true): String {
        val url = URL(if (bRelative) BaseUrl + urlStr else urlStr)
        if (HttpDebug) {
            MyLog.elog("url:$url")
        }
//        return okHttpGet(url) ?: throw RuntimeException("unreceive response")

        val conn = url.openConnection() as HttpURLConnection
        conn.connectTimeout = 5000
        conn.requestMethod = "GET"
        conn.useCaches = false
        val responseCode = conn.responseCode
        if(responseCode != HttpURLConnection.HTTP_OK){
            return responseError(responseCode)
        }

        val reader = BufferedReader(InputStreamReader(conn.inputStream))
        return try {
            val sb = StringBuilder()
            var line = reader.readLine()
            while (line != null){
                sb.append(line)
                line = reader.readLine()
            }
            sb.toString()
        }catch (e:RuntimeException){
            if (HttpDebug){
                e.printStackTrace()
            }
            readHttpResultError()
        }finally {
            reader.close()
        }
    }

    suspend fun post(urlStr: String, paramMap: Map<String, Any>, bRelative: Boolean = true): String {
        val url = URL(if (bRelative) BaseUrl + urlStr else urlStr)
        val conn = url.openConnection() as HttpURLConnection
        conn.connectTimeout = 5000
        conn.requestMethod = "POST"
        conn.doInput = true
        conn.doOutput = true
        conn.useCaches = false

        // 设置请求属性
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded")
        conn.setRequestProperty("Charset", "UTF-8")

        val params = StringBuilder()
        for (key in paramMap) {
            params.append(key).append("=").append(paramMap[key].toString()).append("&")
        }

        val dos = DataOutputStream(conn.outputStream)
        dos.writeBytes(params.toString())
        dos.flush()
        dos.close()

        // 获取返回
        val responseCode = conn.responseCode
        if (responseCode == HttpURLConnection.HTTP_OK) {
            val sb = StringBuilder()
            val reader = BufferedReader(InputStreamReader(conn.inputStream))
            try {
                var line = reader.readLine()
                while (line != null) {
                    sb.append(line)
                    line = reader.readLine()
                }
                return sb.toString()
            } catch (e: Exception) {
                if (HttpDebug) {
                    e.printStackTrace()
                }
                return readHttpResultError()
            } finally {
                reader.close()
            }
        }
        return responseError(responseCode)
    }

//    suspend fun reqServerTime() = get("svrtime")

    suspend fun CoroutineScope.asyncHttpReq(url: String,relative:Boolean =  true): String {
        val start = System.currentTimeMillis()
        val defer = async(Dispatchers.IO) {
            get(url,relative)
        }
        val str = defer.await()
        val spend = System.currentTimeMillis() - start
        MyLog.elog("耗时: spend:${spend} ms")
        MyLog.elog("服务端返回结果:$str")
        return str
    }

//    suspend fun CoroutineScope.asyncHttpReqWithTimeOut(url: String,relative:Boolean =  true) = async(Dispatchers.IO) {
//        get(url,relative)
//    }
//
//    fun blockHttpReq(url: String,relative:Boolean =  true):String{
//        MyLog.info("blockHttpReq called!")
//        return tryGet(url,relative)
//    }
}